perm filename INWAIT.MAC[IP,SYS] blob sn#680215 filedate 1982-10-14 generic text, type T, neo UTF8
;CWL:<403-INET>INWAIT.MAC.40301 29-Jan-82 15:14:32, Edit by CLYNN
; Updated for IP release 3
;[BBNF]<401-INET>INWAIT.MAC.5, 13-Jul-81 12:05:00, Ed: CLYNN
; Fix: Beware wait bit 0

	SEARCH	INPAR,PROLOG
	TTITLE	INWAIT
	SUBTTL	Internet Wait Routines, William W. Plummer 15MAR77
	SWAPCD

COMMENT	!

	INTWTB is a pool of bits which are dynamically assigned to
	things which the INT may have to wait on such as non-resident
	locks, and buffer done conditions.  These bits are in resident
	storage for efficiency reasons.

	INTBFF is a parallel bit table which tells which bits are free.

* ASNWTB ...  3 ...... Assign a wait bit index
* RELWTB ...  3 ...... Deassing a wait bit index

* SETWTB ...  4 ...... Set a wait bit to one state
* CLRWTB ...  4 ...... Clear a wait bit to zero state

* INTBZT ...  5 ...... Scheduler test for wait bit in zero state
* INTBOT ...  5 ...... Scheduler test for wait bit in one state
* INTOOT ...  6 ...... Scheduler test for either of 2 bits on
* INTZOT ...  6 ...... Schecudler test for one bit off or the other on

* WTBINI ...  7 ...... Iniitialize the wait bit table
	!

; Define a TCP-compatible error code (should be a TOPS20 standard error
; code here anyway):

ELT==300

; ASNWBT			Assign a wait bit index

;	CALL ASNWBT
;Ret+1:	Always. T1 has the index or -1,,error

ASNWTB::NOSKED			; Only one process at a time
	MOVSI T3,-NTWBWD	; Number of words in bit table
	SKIPE T1,INTBFF(T3)	; Any free bits in this word?
	JFFO T1,ASNWB1		; Yes.  Get bit number
	AOBJN T3,.-2		; No.  Try next
	JRST ASNWB9		; No free buffer bits

ASNWB1:	MOVE T1,BITS(T2)	; Get the corresponding bit mask
	ANDCAM T1,INTBFF(T3)	; Make it not free
	HRRZS T3		; Get word offset
	IMULI T3,↑D36		; Convert to bits
	ADD T3,T2		; Add bit within last word
	SKIPA T1,T3		; That's the result
ASNWB9:	HRROI T1,ELT+↑D16	; "No space right now"
	OKSKED
	RET



; RELWTB(Index)			; Release the wait bit assignment

;T1/	Bit index to INTWTB
;
;	CALL RELWTB
;Ret+1:	Always.

RELWTB::JUMPE T1,RELWTX		; Beware
	IDIVI T1,↑D36		; Convert to word and bit
	MOVE T2,BITS(T2)	; Get corresponding bit mask
	TDNE T2,INTBFF(T1)	; Better be in use right now.
	 INBUG(HLT,<RELBFR: Bit table fouled up>,INTWA0)
	IORM T2,INTBFF(T1)	; Free it
RELWTX:	RET

; SETWTB(Index)		Set a wait bit to one state

;T1/	Index of bit
;
;	CALL SETWTB
;Ret+1:	Always.

SETWTB::SETZ T2,		; Beware bit 0
	JUMPE T1,SETWTE
	IDIVI T1,↑D36
	MOVE T2,BITS(T2)	; Get bit mask
	TDNE T2,INTBFF(T1)	; Check that it is assigned
SETWTE:	 INBUG(CHK,<SETWTB: Wait bit not assigned>,INTWA1)
	IORM T2,INTWTB(T1)	; Set the bit
	RET



; CLRWTB(Index)		Clear a wait bit to zero state

;T1/	Index of bit
;
;	CALL CLRWTB
;Ret+1:	Always.

CLRWTB::SETZ T2,		; Beware bit 0
	JUMPE T1,CLRWTE
	IDIVI T1,↑D36
	MOVE T2,BITS(T2)
	TDNE T2,INTBFF(T1)
CLRWTE:	 INBUG(CHK,<CLRWTB: Wait bit not assigned>,INTWA2)
	ANDCAM T2,INTWTB(T1)
	RET

; INTBZT(Index)		Scheduler test for a wait bit zero

;T1/	Wait Bit Index
;T4/	Return address
;
;	JSP T4,INTBZT
;Ret+1:	 Bit not zero
;Ret+2:	Bit is zero


	RESCD
INTBZT::JUMPE T1,INTBZX		; Beware bit 0
	IDIVI T1,↑D36		; Convert to word and bit numbers
	MOVE T2,BITS(T2)	; Get bit mask
	TDNE T2,INTWTB(T1)	; Zero yet?
	 JRST 0(T4)		; No
INTBZX:	JRST 1(T4)



; INTBOT(Index)			Scheduler test for a wait bit being on

;T1/	Index to INTWTB
;T4/	Return address
;
;	JSP T4,INTBOT
;Ret+1:	 Wait flag still off
;Ret+2:	Wait flag now on

INTBOT::JUMPE T1,INTBOX		; Beware bit 0
	IDIVI T1,↑D36
	MOVE T2,BITS(T2)
	TDNN T2,INTWTB(T1)
	 JRST 0(T4)
INTBOX:	JRST 1(T4)

; INTOOT(Index1, Index2)	Scheduler test for either of 2 bits
;				becoming a one

;T1/	Index1 in left half of right half, Index 2 in RH of RH
;T4/	Return address
;
;	JSP T4,INTOOT
;Ret+1:	Both bits are still off
;Ret+2:	One or both of the bits are now on

INTOOT::IDIVI T1,1000		; Index1 to T1, Index2 to T2
	MOVE T3,T2		; Save Index2
	JUMPE T1,INTOOX		; Beware bit 0
	IDIVI T1,↑D36		; Separate in to word and bit number
	MOVE T2,BITS(T2)	; Get the bit
	TDNE T2,INTWTB(T1)	; Is bit1 on?
	 JRST 1(T4)		; Yes.  Give skip return.
	MOVE T1,T3		; Get Index2
	JUMPE T1,INTOOX		; Beware bit 0
	IDIVI T1,↑D36
	MOVE T2,BITS(T2)
	TDNN T2,INTWTB(T1)	; Is that bit on?
	 JRST 0(T4)		; No.
INTOOX:	 JRST 1(T4)		; Yes.



; INTZOT(Index1, Index2)	Scheduler test for either one bit
;				becoming a 0 or the other becoming a 1

;T1/	Index1 in left half of right half, Index 2 in RH of RH
;T4/	Return address
;
;	JSP T4,INTZOT
;Ret+1:	Index1 still on and Index2 still off
;Ret+2:	Either Index1 has gone off or Index2 has come on, or both

INTZOT::IDIVI T1,1000		; Index1 to T1, Index2 to T2
	MOVE T3,T2		; Save Index2
	JUMPE T1,INTZOX		; Beware bit 0
	IDIVI T1,↑D36		; Get word and bit number
	MOVE T2,BITS(T2)	; Get the bit
	TDNN T2,INTWTB(T1)	; Is bit1 off?
	 JRST 1(T4)		; Yes.  Give skip return.
	MOVE T1,T3		; Get Index2
	JUMPE T1,INTZOX		; Beware bit 0
	IDIVI T1,↑D36
	MOVE T2,BITS(T2)
	TDNN T2,INTWTB(T1)	; Is bit2 on?
	 JRST 0(T4)		; No.
INTZOX:	 JRST 1(T4)		; Yes.

	SWAPCD

; WTBINI		Initialize Buffer Free Flag pool

;	CALL WTBINI
;Ret+1:	Always.

WTBINI::MOVSI T1,-NTWBWD	; Number of words in the pool
	MOVE T2,[-1-1B0]	; Never use index 0
	MOVEM T2,INTBFF(T1)	; Clear free flags
	SETO T2,
	AOBJN T1,.-2
	RET

	TNXEND
	END